package org.fxml.utils {
	import org.fxml.IObject;

	import mx.utils.DescribeTypeCache;

	import flash.display.DisplayObjectContainer;
	import flash.utils.ByteArray;
	import flash.utils.Proxy;

	/**
	 * @author jordandoczy
	 */
	public class ObjectUtil {
		
		public static function getValue(chain:*, object:*):*{
				
			if(chain == "this") return object;
			if(chain is String){
				chain = chain.replace("[", ".");
				chain = chain.replace("]", "");	
				chain = chain.split(".");
				
				/* XML E4X Support (Buggy)
				if(chain.indexOf("@") != -1){ // HACK
					try{
						var pattern:RegExp = new RegExp("['\"](.*)['\"]");
						var results:Array = chain.match(pattern);
						var tmp:String = results[1].replace(new RegExp("[.]", "g"), "~");
						chain = chain.replace(results[1], tmp);
						
						chain = chain.split(".");
						for (var i:uint = 0; i<chain.length; i++){
							chain[i] = chain[i].replace(new RegExp("[~]", "g"), ".");
						}
					}
					catch(e:Error){
						chain = chain.split(".");
					}
				}
				else{
					chain = chain.split(".");
				}
				 */
			}
			
			var property:*; 
			
			/*  XML E4X Support (Buggy)
			if(object is XML || object is XMLList){
				if(chain[0].indexOf("@") != -1){
					var attributePattern:RegExp = new RegExp("@([A-Za-z0-9_.]*).*==");
					var attr:Array = chain[0].match(attributePattern);
					var valuePattern:RegExp = new RegExp("['\"](.*)['\"]");
					var value:Array = chain[0].match(valuePattern);
					property = (object).(attribute(attr[1]) == value[1]);
				}
				else{
					property = object[chain[0]];
				}
			}
			else 
			 */
			
			if(object is Proxy){
				property = object[chain[0]];
			}
			else if(object is IObject && IObject(object).hasProperty(chain[0])){
				property = IObject(object).getProperty(chain[0]);
			}
			else if(object.hasOwnProperty(chain[0])){
				property = object[chain[0]];
			}
			else if(object is DisplayObjectContainer){
				try{
					property = object.getChildByName(chain[0]);
				}
				catch(e:Error){}
			}
			
			if(chain is Array && chain.length > 1) return getValue(chain.slice(1), property);
			else return property;
		}
		
		public static function isDynamic(object:*):Boolean {
		    var type:XML = DescribeTypeCache.describeType(object).typeDescription;
		    if(type.isDynamic) return true;
		    return false;
		}
		
		public static function isEqual(value1:*, value2:*):Boolean{
			return value1 === value2;
		}
		
		public static function clone(source:Object):* {
		    var copier:ByteArray = new ByteArray();
		    copier.writeObject(source);
		    copier.position = 0;
		    return(copier.readObject());
		}
		
	}
}